package dao;


import com.sun.org.apache.xerces.internal.impl.dtd.models.DFAContentModel;
import lombok.Data;
import model.DatabaseConnectParameter;
import model.DatabaseFrom;
import model.DatabaseFromColumn;

import java.sql.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author： 杨浩然
 * @date： 2023-01-31 17:44
 */

public class DatabaseConnectDao {
    private Connection conn = null;

    public Connection getConn(DatabaseConnectParameter dcp) {
        try {
            //获取连接对象Connection
            Class.forName(dcp.getDriver());
            conn = DriverManager.getConnection(dcp.getConnecturl(), dcp.getUsername(), dcp.getPassword());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
            close();
        }
        return conn;
    }

    public void close() {
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    public Map<String, DatabaseFrom> findDataBaseFroms(DatabaseConnectParameter databaseConnectParameter) {
        getConn(databaseConnectParameter);
        Map<String, DatabaseFrom> fromMap = new HashMap<String, DatabaseFrom>();
        for (String name :
                databaseConnectParameter.getFromname()) {
            Map<String, DatabaseFromColumn> datamap = new HashMap<String, DatabaseFromColumn>();
            try {
                DatabaseMetaData metaData = conn.getMetaData();
//                ResultSet colRet = metaData.getColumns(null, "%", name, "%");
                ResultSet colRet = metaData.getColumns(null, databaseConnectParameter.getSchemaPattern(), name, "%");
                while (colRet.next()) {
                    String columnName = colRet.getString("COLUMN_NAME"); //列名称
                    String columnType = colRet.getString("TYPE_NAME");//数据源依赖的类型名称，对于 UDT，该类型名称是完全限定的
                    String REMARKS = colRet.getString("REMARKS");//描述列的注释
                    int datasize = colRet.getInt("COLUMN_SIZE");//列的大小
                    int digits = colRet.getInt("DECIMAL_DIGITS");//小数部分的位数。
                    int nullable = colRet.getInt("NULLABLE");//是否允许使用 NULL。
//                System.out.println(columnName + " " + columnType + " " + datasize + " " + digits + " " + nullable + " " + REMARKS);
                    DatabaseFromColumn databaseFromColumn = new DatabaseFromColumn();
                    databaseFromColumn.setCOLUMN_NAME(columnName);
                    databaseFromColumn.setTYPE_NAME(columnType);
                    databaseFromColumn.setREMARKS(REMARKS);
                    databaseFromColumn.setCOLUMN_SIZE(datasize);
                    databaseFromColumn.setDECIMAL_DIGITS(digits);
                    databaseFromColumn.setNULLABLE(nullable);
                    //KEY全部大写 匹配到后再具体对比
                    datamap.put(columnName.toUpperCase(), databaseFromColumn);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            DatabaseFrom databaseFrom = new DatabaseFrom();
            databaseFrom.setFromName(name);
            databaseFrom.setFromRemarks(name);
            databaseFrom.setColumnMap(datamap);
            fromMap.put(name, databaseFrom);
        }
        close();
        return fromMap;
    }


//    public Map<String, DatabaseFromColumn> findDataBaseFrom(DatabaseConnectParameter databaseConnectParameter) {
//        getConn(databaseConnectParameter);
//        Map<String, DatabaseFromColumn> datamap=new HashMap<String, DatabaseFromColumn>();
//        try {
//            DatabaseMetaData metaData = conn.getMetaData();
//            ResultSet colRet = metaData.getColumns(null, "%", "bgyf_courtyard", "%");
//            while (colRet.next()) {
//                String columnName = colRet.getString("COLUMN_NAME"); //列名称
//                String columnType = colRet.getString("TYPE_NAME");//数据源依赖的类型名称，对于 UDT，该类型名称是完全限定的
//                String REMARKS = colRet.getString("REMARKS");//描述列的注释
//                int datasize = colRet.getInt("COLUMN_SIZE");//列的大小
//                int digits = colRet.getInt("DECIMAL_DIGITS");//小数部分的位数。
//                int nullable = colRet.getInt("NULLABLE");//是否允许使用 NULL。
////                System.out.println(columnName + " " + columnType + " " + datasize + " " + digits + " " + nullable + " " + REMARKS);
//                DatabaseFromColumn databaseFromColumn=new DatabaseFromColumn();
//                databaseFromColumn.setColumnName(columnName);
//                databaseFromColumn.setColumnType(columnType);
//                databaseFromColumn.setRemarks(REMARKS);
//                databaseFromColumn.setDatasize(datasize);
//                databaseFromColumn.setDigits(digits);
//                databaseFromColumn.setNullable(nullable);
//                datamap.put(columnName,databaseFromColumn);
//            }
//        } catch (SQLException e) {
//            e.printStackTrace();
//        }
//        return datamap;
//    }


//    每个列描述都有以下列：
//
//    TABLE_CAT String => 表类别（可为 null）
//    TABLE_SCHEM String => 表模式（可为 null）
//    TABLE_NAME String => 表名称
//    COLUMN_NAME String => 列名称
//    DATA_TYPE int => 来自 java.sql.Types 的 SQL 类型
//    TYPE_NAME String => 数据源依赖的类型名称，对于 UDT，该类型名称是完全限定的
//    COLUMN_SIZE int => 列的大小。
//    BUFFER_LENGTH 未被使用。
//    DECIMAL_DIGITS int => 小数部分的位数。对于 DECIMAL_DIGITS 不适用的数据类型，则返回 Null。
//    NUM_PREC_RADIX int => 基数（通常为 10 或 2）
//    NULLABLE int => 是否允许使用 NULL。
//    columnNoNulls - 可能不允许使用 NULL 值
//    columnNullable - 明确允许使用 NULL 值
//    columnNullableUnknown - 不知道是否可使用 null
//    REMARKS String => 描述列的注释（可为 null）
//    COLUMN_DEF String => 该列的默认值，当值在单引号内时应被解释为一个字符串（可为 null）
//    SQL_DATA_TYPE int => 未使用
//    SQL_DATETIME_SUB int => 未使用
//    CHAR_OCTET_LENGTH int => 对于 char 类型，该长度是列中的最大字节数
//    ORDINAL_POSITION int => 表中的列的索引（从 1 开始）
//    IS_NULLABLE String => ISO 规则用于确定列是否包括 null。
//    YES --- 如果参数可以包括 NULL
//    NO --- 如果参数不可以包括 NULL
//    空字符串 --- 如果不知道参数是否可以包括 null
//    SCOPE_CATLOG String => 表的类别，它是引用属性的作用域（如果 DATA_TYPE 不是 REF，则为 null）
//    SCOPE_SCHEMA String => 表的模式，它是引用属性的作用域（如果 DATA_TYPE 不是 REF，则为 null）
//    SCOPE_TABLE String => 表名称，它是引用属性的作用域（如果 DATA_TYPE 不是 REF，则为 null）
//    SOURCE_DATA_TYPE short => 不同类型或用户生成 Ref 类型、来自 java.sql.Types 的 SQL 类型的源类型（如果 DATA_TYPE 不是 DISTINCT 或用户生成的 REF，则为 null）
//    IS_AUTOINCREMENT String => 指示此列是否自动增加
//    YES --- 如果该列自动增加
//    NO --- 如果该列不自动增加
//    空字符串 --- 如果不能确定该列是否是自动增加参数
//    COLUMN_SIZE 列表示给定列的指定列大小。对于数值数据，这是最大精度。对于字符数据，这是字符长度。对于日期时间数据类型，这是 String 表示形式的字符长度（假定允许的最大小数秒组件的精度）。对于二进制数据，这是字节长度。对于 ROWID 数据类型，这是字节长度。对于列大小不适用的数据类型，则返回 Null。
//
//    参数：
//    catalog - 类别名称；它必须与存储在数据库中的类别名称匹配；该参数为 "" 表示获取没有类别的那些描述；为 null 则表示该类别名称不应该用于缩小搜索范围
//    schemaPattern - 模式名称的模式；它必须与存储在数据库中的模式名称匹配；该参数为 "" 表示获取没有模式的那些描述；为 null 则表示该模式名称不应该用于缩小搜索范围
//    tableNamePattern - 表名称模式；它必须与存储在数据库中的表名称匹配
//    columnNamePattern - 列名称模式；它必须与存储在数据库中的列名称匹配

}
